<?php
/**
 * Created by PhpStorm.
 * User: cc
 * Date: 2023/8/2
 * Time: 10:41 AM
 */

namespace app\common\cachemodel\zlcr3;

use app\common\cachemodel\ZlcrAstr;
use app\common\cachemodel\ZlcrTag;
use app\common\lib\Util;
use app\common\model\BaseCache;
use app\zyhsapi\model\ZyhsAstrLevelGradeChangeRecode;
use app\zyhsapi\model\ZyhsAstrPauseRecord;
use app\zyhsapi\model\ZyhsConfig;
use think\Db;
use XznsTools\cache\CacheManage;

class Zlcr3ConsultAccount extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zlcr3_consult_account';

    protected $cacheModel = 'astr_admin.consult_account';

    /**
     * 占星师等级对应的最小能力分
     * @var int[]
     */
    public $astrLevelMinScore = [
        1 => 0,         // 大于等于0的能力分，等级为1
        2 => 2000,      // 大于等于2000的能力分，等级为2
        3 => 5000,      // 大于等于5000的能力分，等级为3
        4 => 10000,     // 大于等于10000的能力分，等级为4
        5 => 30000,     // 大于等于30000的能力分，等级为5
        6 => 100000,    // 大于等于100000的能力分，等级为6
    ];

    public $rtcModifyPriceData = [
        1 => ['min_price' => 100, 'max_price' => 100],
        2 => ['min_price' => 100, 'max_price' => 150],
        3 => ['min_price' => 120, 'max_price' => 200],
        4 => ['min_price' => 150, 'max_price' => 250],
        5 => ['min_price' => 180, 'max_price' => 300],
        6 => ['min_price' => 200, 'max_price' => 350],
    ];

    /**
     * 获取对应的问题评论信息
     * @param array $ids
     * @param array|null $type
     * @param string $sortType
     * @return array
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        $where = ['astr_id' => ['in', $ids]];
        try
        {
            $data = $this->where($where)->column('*', 'astr_id');
        }
        catch (\Exception $e)
        {
            $data = [];
        }
        return $data;
    }

    public function batchGetInfoByIds($cids, $field = [])
    {
        $resData = parent::batchGetInfoByIds($cids, $field);

        return $this->dataInit($resData);
    }

    /**
     * 数据初始化
     * @param array $data
     * @return array
     */
    public function dataInit(array $data)
    {
        $baseIncData = [
            121169 => [
                'service_duration' => 629,
                'service_num' => 25,
                'recommended_nums' => 28,
            ],
            121789 => [
                'service_duration' => 755,
                'service_num' => 32,
                'recommended_nums' => 28,
            ],
            123109 => [
                'service_duration' => 786,
                'service_num' => 29,
                'recommended_nums' => 33,
            ],
            1224206 => [
                'service_duration' => 667,
                'service_num' => 28,
                'recommended_nums' => 25,
            ],
            1224207 => [
                'service_duration' => 617,
                'service_num' => 32,
                'recommended_nums' => 24,
            ],
            1224213 => [
                'service_duration' => 749,
                'service_num' => 26,
                'recommended_nums' => 20,
            ],
            49269 => [
                'service_duration' => 742,
                'service_num' => 27,
                'recommended_nums' => 26,
            ],
            110509 => [
                'service_duration' => 631,
                'service_num' => 31,
                'recommended_nums' => 34,
            ],
            116444 => [
                'service_duration' => 644,
                'service_num' => 29,
                'recommended_nums' => 24,
            ],
            106011 => [
                // 单位 分钟
                'service_duration' => 853,
                'service_num' => 59,
                'recommended_nums' => 58,
            ],
            116225 => [
                // 单位 分钟
                'service_duration' => 508,
                'service_num' => 50,
                'recommended_nums' => 47,
            ],
            1225830 => [
                'service_duration' => 781,
                'service_num' => 40,
                'recommended_nums' => 33,
            ],
            1225802 => [
                'service_duration' => 733,
                'service_num' => 42,
                'recommended_nums' => 32,
            ],
            1226385 => [
                'service_duration' => 664,
                'service_num' => 36,
                'recommended_nums' => 29,
            ],
            107295 => [
                'service_duration' => 612,
                'service_num' => 39,
                'recommended_nums' => 26,
            ],
            1226851 => [
                'service_duration' => 721,
                'service_num' => 44,
                'recommended_nums' => 34,
            ],
            1225861 => [
                'service_duration' => 613,
                'service_num' => 38,
                'recommended_nums' => 28,
            ],
            92077 => [
                'service_duration' => 760,
                'service_num' => 39,
                'recommended_nums' => 33,
            ],
            1225843 => [
                'service_duration' => 578,
                'service_num' => 40,
                'recommended_nums' => 26,
            ],
        ];

        foreach ($data as $index => $itemData)
        {
            $data[$index] = arrayKeyData2int($itemData, ['astr_id', 'status', 'level', 'level_score', 'consult_status', 'price', 'service_num', 'service_duration', 'recommended_nums', 'invite_aid', 'aid', 'create_time', 'update_time', 'team_id']);

            if (isset($itemData['percent']))
            {
                $data[$index]['percent'] = $itemData['percent'] ? json_decode($itemData['percent'], true) : [];
            }

            if (isset($itemData['tags']))
            {
                $data[$index]['tags'] = $itemData['tags'] ? explode(',', $itemData['tags']) : [];
            }

            if (isset($itemData['tids']))
            {
                $tids = $itemData['tids'] ? explode(',', $itemData['tids']) : [];
                $data[$index]['tids'] = array_map('intval', $tids);
            }

            if (isset($itemData['zone_tids']))
            {
                $zoneIds = $itemData['zone_tids'] ? explode(',', $itemData['zone_tids']) : [];
                $data[$index]['zone_tids'] = array_map('intval', $zoneIds);
            }

            if (isset($itemData['extend']))
            {
                $data[$index]['extend'] = $itemData['extend'] ? json_decode($itemData['extend'], true) : [];
                $data[$index]['ability_score'] = $data[$index]['extend']['ability_score'] ?? 0;// 专业排行预设值
                $data[$index]['hot_score'] = $data[$index]['extend']['hot_score'] ?? 0;// 热度排行预设值
            }

            // 增加基数
            if (isset($baseIncData[$index]))
            {
                if (isset($itemData['service_duration']))
                {
                    $data[$index]['service_duration'] = $itemData['service_duration'] + ($baseIncData[$index]['service_duration'] * 60);
                }
                if (isset($itemData['service_num']))
                {
                    $data[$index]['service_num'] = $itemData['service_num'] + $baseIncData[$index]['service_num'];
                }
                if (isset($itemData['recommended_nums']))
                {
                    $data[$index]['recommended_nums'] = $itemData['recommended_nums'] + $baseIncData[$index]['recommended_nums'];
                }
            }
        }

        return $data;
    }

    /**
     * 获取指定  咨询师Ids
     * @param int $type 0=>全部 专区
     * @return array
     * @throws \Exception
     */
    public function getChatConsultIds(int $type, int $page = 1, int $limit = 10)
    {
        $resData = CacheManage::getInstance()
            ->setCacheConfig($this->cacheModel, 0)
            ->setListKeyType($type)
            ->setPage($page)
            ->setPageSize($limit)
            ->setSort('desc')
            ->getListPageDataIds(function ($isCache = true, $sortType = 'desc') use ($type)
            {
                try
                {
                    if ($type)
                    {
                        $where = "`consult_status` = 1 AND FIND_IN_SET({$type},`zone_tids`)";
                    } else
                    {
                        $where = '`consult_status` = 1 AND NOT FIND_IN_SET(999,`zone_tids`)';
                    }

                    $data = $this->where($where)->column('astr_id');
                    $resData = [];
                    foreach ($data as $id)
                    {
                        $resData[$id] = ['sort' => $id];
                    }

                    return $resData;
                }
                catch (\Exception $e)
                {
                    return [];
                }
            }, 'sort', 0);
        $resData['data'] = array_keys($resData['data']);

        return $resData;
    }

    /**
     * 获取 技能标签信息
     * @param array $tids
     * @return array
     * @throws \Exception
     */
    public function getTags(array $tids)
    {
        if (empty($tids))
        {
            return [];
        }
        $tagInfos = (new ZlcrTag())->batchGetInfoByIds($tids);

        $t = [];
        foreach ($tagInfos as $id => $tagItem)
        {
            //技能标签华为修改规则：如果只有Tarot，那么改为心理；如果包含Tarot 和 心理，那么去掉Tarot；
            if (($tagItem['tag_name'] === 'Tarot') && Util::IsHuawei())
            {
                $tagItem['tag_name'] = '心理';
            }
            $t[sprintf('%.8f', $tagItem['sort'] + $id / 100000000)] = $tagItem['tag_name'];
        }
        krsort($t);

        return array_values(array_unique($t));
    }

    /**
     * 获取 徽章 标签信息
     * @param array $tagIconIds
     * @return array
     * @throws \Exception
     */
    public function getTagsIcon(array $tagIconIds)
    {
        if (empty($tagIconIds))
        {
            return [];
        }
        $tagIconInfos = (new ZlcrTag())->batchGetInfoByIds($tagIconIds);

        $t = [];
        foreach ($tagIconInfos as $id => $tagIconItem)
        {
            $t[sprintf('%.8f', $tagIconItem['sort'] + $id / 100000000)] = $tagIconItem['templet_url'];
        }
        krsort($t);

        return array_values($t);
    }

    /**
     * 更新 咨询师 信息
     * @param int $astrId
     * @param array $data
     * @return bool
     */
    public function updateData(int $astrId, array $data)
    {
        try
        {   //
            $data['update_time'] = time();
            $this->where(['astr_id' => $astrId])->update($data);

            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $astrId)->rmCache();
            return true;
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            return false;
        }
    }

    /**
     * 获取 咨询榜单信息
     */
    public function rankingData(array $data)
    {
        $testAccountConfig = (new ZyhsConfig())->configInfo('rtc');
        $testAccount = isset($testAccountConfig['test_user']) && $testAccountConfig['test_user'] ? explode(',', $testAccountConfig['test_user']) : [];
        $resData = [];
        $zlcrAstrModel = new ZlcrAstr();
        $zlcrTagModel = new ZlcrTag();
        foreach ($data as $astrId => $score)
        {
            if (in_array($astrId, $testAccount, false))
            {
                continue;
            }
            $astrInfo = $zlcrAstrModel->getInfoById($astrId);
            $consultAstrInfo = $this->getInfoById($astrId);

            $tags = [];
            if ($consultAstrInfo['tags'])
            {
                $tagList = $zlcrTagModel->batchGetInfoByIds($consultAstrInfo['tags']);
                foreach ($tagList as $tagInfo)
                {
                    $tags[] = $tagInfo['tag_name'];
                }
            }
            $resData[] = [
                'id' => $astrId,
                'avatar' => $astrInfo['avatar'],
                'name' => $astrInfo['nickname'],
                'tags' => $tags,
                'status' => $consultAstrInfo['status'] === 1 ? 1 : 0,
                'score' => $score > 0 ? (int)$score : 0,
            ];
        }

        return $resData;
    }

    /**
     * 取分成比例
     * @param array $percentData 分成信息
     * @param int $serverNum 本次服务次数 【历史已服务次数 + 1】
     * @return float
     */
    public function getPercent(array $percentData, int $serverNum)
    {
        switch (true)
        {
            case $serverNum === 1:
                return $percentData[1] ?? 0.25;
            case $serverNum >= 2 && $serverNum <= 5:
                return $percentData[2] ?? 0.3;
            case $serverNum >= 6 && $serverNum <= 10:
                return $percentData[3] ?? 0.35;
            default:
                return $percentData[4] ?? 0.4;
        }
    }

    /**
     * 获取 咨询师 跳转连接
     * @param int $astrId
     * @return array
     */
    public function getAstrTargetLink(int $astrId)
    {
        $consultAccountInfo = $this->getInfoById($astrId);
        $data = [
            'target' => 'local',
            'link' => '',
        ];
        if ($consultAccountInfo && $consultAccountInfo['consult_status'] === 1)
        {   // 跳转至咨询师主页
            $data = [
                'target' => 'local',
                'link' => "astro_index?id={$astrId}&need_auth=0",
            ];
        }

        return $data;
    }

    /**
     * 取 问答 分成比例
     * @return array
     */
    public function getQuestionAnswerPercent()
    {
        return [
            'question' => 0.25, // 问答问题分成比例为25%
            'add_question' => 0.5,  // 问答追问分成比例为50%
        ];
    }

    /**
     * 获取 问答咨询师 能解答的问题类型
     * @param array $consultAccountInfo
     * @return array
     */
    public function getAstroQuestionType(array $consultAccountInfo)
    {
        // 如果没有接单资格 则 返回 空
        $questionPauseTime = $consultAccountInfo['extend']['question_pause_time'] ?? 0;
        if (isset($consultAccountInfo['extend']['question_tags']) && $questionPauseTime < time())
        {   // 有接单资格 并且 未暂停
            $questionTags = explode(',', $consultAccountInfo['extend']['question_tags']);
            if ($questionTags)
            {
                $questionTags = array_map('intval', $questionTags);
            }
        }

        return $questionTags ?? [];
    }

    /**
     * 修改 咨询师 能力分数
     * @param array $consultAccountInfo // 咨询师信息
     * @param int $taskId 任务id
     * @param int $taskType 1=>连线咨询 2=>问答
     * @param int $changeScore 更新能力值
     * @param int $type 类型  1=>评价 2=>被申述 3=>问答回复超时  4=>问答追问回复超时 5=>连线时长 6=>被推荐
     * @param int $pauseTime 冻结时长
     * @param string $pauseReason
     * @return void
     */
    public function changeAstrLevelScore(array $consultAccountInfo, int $taskId, int $taskType, int $changeScore, int $type, int $pauseTime = 0, string $pauseReason = '')
    {
        try
        {
            $nowTime = time();
            $resScore = $consultAccountInfo['level_score'] + $changeScore;
            $resLevel = 1;
            foreach ($this->astrLevelMinScore as $level => $score)
            {
                if ($resScore >= $score && $resLevel < $level)
                {
                    $resLevel = $level;
                }
            }
            $updateData = [
                'level_score' => $resScore,
            ];
            if ($resLevel !== $consultAccountInfo['level'])
            {
                $updateData['level'] = $resLevel;
            }
            if ($resLevel !== $consultAccountInfo['level'] && ($consultAccountInfo['price'] < $this->rtcModifyPriceData[$resLevel]['min_price'] || $consultAccountInfo['price'] > $this->rtcModifyPriceData[$resLevel]['max_price']))
            {   // 咨询师 等级 更新
                $updateData['price'] = $this->rtcModifyPriceData[$resLevel]['min_price'];
            }
            $questionPauseTime = $consultAccountInfo['extend']['question_pause_time'] ?? 0;
            if ($questionPauseTime > $nowTime && $questionPauseTime > $pauseTime)
            {   // 账号已经冻结了 并且 冻结时长大于 当前冻结时长 则忽略 本次冻结
                $pauseTime = 0;
            }
            if ($pauseTime > $nowTime)
            {   // 冻结账号 问答接单资格
                $consultAccountInfo['extend']['question_pause_time'] = $pauseTime;
                $updateData['extend'] = json_encode($consultAccountInfo['extend'], true);
            }
            if ($taskType === 1 && $type === 6)
            {   // 被推荐 推荐次数+1
                $updateData['recommended_nums'] = Db::raw('recommended_nums + 1');
            }
            // 更新咨询师能力分 等级信息
            $this->updateData($consultAccountInfo['astr_id'], $updateData);
            if ($pauseTime && $taskType === 2) // 问答 类型 冻结  冻结问答接单资格
            {   // 写入 冻结记录
                (new ZyhsAstrPauseRecord())->insert([
                    'astr_id' => $consultAccountInfo['astr_id'],
                    'task_type' => 2,   // 1=>连线咨询 2=>问答
                    'pause_reason' => $pauseReason, // 记录 冻结原因
                    'create_time' => $pauseTime,
                ]);
            }
            $recordData = [
                'astr_id' => $consultAccountInfo['astr_id'],
                'task_id' => $taskId,
                'task_type' => $taskType,
                'change' => $changeScore,   // 变动能力值
                'astro_grade' => $resScore, // 变动后能力值
                'type' => $type,
                'create_time' => $nowTime,
            ];
            // 写入 更新记录
            (new ZyhsAstrLevelGradeChangeRecode())->addRecord($recordData);
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
        }
    }


    /**
     * 冻结 咨询师 问答接单资格
     * @param array $consultAccountInfo
     * @param int $pauseTime
     * @param string $pauseReason
     * @return void
     */
    public function pauseAstrQuestionAnswer(array $consultAccountInfo, int $pauseTime = 0, string $pauseReason = '')
    {
        try
        {
            $questionPauseTime = $consultAccountInfo['extend']['question_pause_time'] ?? 0;
            if ($questionPauseTime > $pauseTime)
            {   // 账号已经冻结了
                return;
            }
            $consultAccountInfo['extend']['question_pause_time'] = $pauseTime;
            $updateData['extend'] = json_encode($consultAccountInfo['extend'], true);
            // 更新咨询师能力分 等级信息
            $this->updateData($consultAccountInfo['astr_id'], $updateData);

            (new ZyhsAstrPauseRecord())->insert([
                'astr_id' => $consultAccountInfo['astr_id'],
                'task_type' => 2,   // 1=>连线咨询 2=>问答
                'pause_reason' => $pauseReason, // 记录 冻结原因
                'create_time' => $pauseTime,
            ]);
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
        }
    }
}
